#include  "HalExvStepMotor.h"

/*************************************************************
* Struct variable in File
*************************************************************/
ST_APP_STEP_OUTPUT stStepOut[U8_HALMOTOR_MAX];
static ST_APP_STEP_INPUT stStepInput[U8_HALMOTOR_MAX];
static ST_APP_STEP_PARA stStepPara[U8_HALMOTOR_MAX];

/*************************************************************
* Variable in File
*************************************************************/
uint8 u8Chn = 0;    //通道（主循环使用）
uint8 u8IerChn = 0; //通道（中断使用）
const uint8 aStepDrvTab[] = //电机驱动表格 1-2相励磁 正向
{
    0x08, 0x0c, 0x04, 0x06, 0x02, 0x03, 0x01, 0x09
};

const uint8 aStepDrvRevTab[] = //电机驱动表格 1-2相励磁 反向
{
    0x09, 0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08
};

/*************************************************************
* Function in File
*************************************************************/
static void HalStepPowerOn(void);
static void HalStepUpd(void);
static void HalStepAct(void);
static void HalStepInput(void);

/******************************************************************************
* Function Name: HalStepCtrl
* Description: 主控函数
* Output:  void
*******************************************************************************/
void HalStepCtrl(void)
{
    for (u8Chn = 0; u8Chn < U8_HALMOTOR_MAX; u8Chn++)
    {
        HalStepInput();

        if (0 == stStepOut[u8Chn].u8PowerOnInit)
        {
            HalStepPowerOn();
        }
        else
        {
            HalStepUpd();
        }
    }
}

/******************************************************************************
* Function Name: HalStepPowerOn
* Description: 上电复位相关参数赋值
* Output:  void
*******************************************************************************/
void HalStepPowerOn(void)
{
    if (0 != GetTimeBase4ms())
    {
        if (stStepPara[u8Chn].u8InitTim < 0xff)
        {
            stStepPara[u8Chn].u8InitTim++;
        }
    }

    if (stStepPara[u8Chn].u8InitTim > U8_STEP_INTERVAL_TIM)
    {
        stStepOut[u8Chn].u8PowerOnInit = 1;
        stStepPara[u8Chn].s16TargPls = 0;   //目标步数为0
        stStepPara[u8Chn].s16CurPls = stStepInput[u8Chn].s16ResetPls;  //当前步数为上电复位开度
        stStepOut[u8Chn].u8ExvBusy = U8_STEP_STA_BUSY;
    }

    stStepPara[u8Chn].u16PaceHoldTim = 0;
}

/******************************************************************************
* Function Name: HalStepSpeed
* Description: 励磁计时(500us执行一次)
* Output:  void
*******************************************************************************/
void HalStepSpeed(void)
{
    //仅在动作时才计时，确保初始拍励磁时间
    for (u8IerChn = 0; u8IerChn < U8_HALMOTOR_MAX; u8IerChn++)
    {
        if (U8_STEP_STA_BUSY == stStepOut[u8IerChn].u8ExvBusy)
        {
            stStepPara[u8IerChn].u8DrvSpeedTim++;
        }
        else
        {
            stStepPara[u8IerChn].u8DrvSpeedTim = 0;
        }

        HalStepAct();
    }
}

/******************************************************************************
* Function Name: HalStepUpd
* Description: 目标开度更新
* Output:  void
*******************************************************************************/
static void HalStepUpd(void)
{
    //阀需要空闲状态才更新输入开度
    if (((1 == stStepInput[u8Chn].u8InStepType) || (U8_STEP_STA_IDLE == stStepOut[u8Chn].u8ExvBusy))
        && (TRUE == stStepOut[u8Chn].u8RstFinish) && (TRUE == stStepPara[u8Chn].u8OnceDrvOver))
    {
        if (stStepPara[u8Chn].s16TargPls != stStepInput[u8Chn].s16InTargPls)
        {
            stStepPara[u8Chn].s16TargPls = stStepInput[u8Chn].s16InTargPls;
            stStepPara[u8Chn].u8DrvSpeedTim = 0;

            //步进电机动作过程中收到新的目标步数时，不做500ms励磁
            if ((1 == stStepInput[u8Chn].u8InStepType) && (U8_STEP_STA_BUSY == stStepOut[u8Chn].u8ExvBusy))
            {
                if (stStepPara[u8Chn].u16PaceHoldTim >= U16_STEP_START_TIM)
                {//判断动作前励磁时间<500ms，则不做处理，避免励磁时间未满500ms前，目标步数变化导致励磁时间直接赋值500ms
                    stStepPara[u8Chn].u16PaceHoldTim = U16_STEP_START_TIM;
                }
            }
            else
            {
                stStepPara[u8Chn].u16PaceHoldTim = 0;
            }

            //阀目标开度为0时，需要多关
            if ((0 == stStepPara[u8Chn].s16TargPls) && (0 == stStepInput[u8Chn].u8InStepType))
            {
                stStepPara[u8Chn].s16ClosePls = stStepInput[u8Chn].s16InClosePls;
            }

            stStepOut[u8Chn].u8ExvBusy = U8_STEP_STA_BUSY;
        }
    }
}

/******************************************************************************
* Function Name: HalStepAct
* Description: 目标开度执行(500us中断调用)
* Output:  void
*******************************************************************************/
static void HalStepAct(void)
{
    if ((stStepPara[u8IerChn].s16CurPls != stStepPara[u8IerChn].s16TargPls)
        || (0 != stStepPara[u8IerChn].s16ClosePls))
    {
        stStepPara[u8IerChn].u8OnceDrvOver = FALSE;
        
        //动作前电平维持时间
        if (stStepPara[u8IerChn].u16PaceHoldTim > U16_STEP_START_TIM)
        {
            if (stStepPara[u8IerChn].u8DrvSpeedTim >= stStepInput[u8IerChn].u8InDrvSpeedSet)
            {
                stStepPara[u8IerChn].u8DrvSpeedTim = 0;
                stStepPara[u8IerChn].u8OnceDrvOver = TRUE;

                if (stStepPara[u8IerChn].s16CurPls > stStepPara[u8IerChn].s16TargPls)
                {
                    stStepPara[u8IerChn].s16CurPls--;
                    stStepPara[u8IerChn].u8DrvDire = U8_STEP_DIRE_CLOSE;
                }
                else if (stStepPara[u8IerChn].s16CurPls < stStepPara[u8IerChn].s16TargPls)
                {
                    stStepPara[u8IerChn].s16CurPls++;
                    stStepPara[u8IerChn].u8DrvDire = U8_STEP_DIRE_OPEN;
                }
                else//关阀清零时，阀体关0P后继续关
                {
                    stStepPara[u8IerChn].s16ClosePls--;
                    stStepPara[u8IerChn].u8DrvDire = U8_STEP_DIRE_CLOSE;
                }

                if (U8_STEP_DIRE_OPEN == stStepPara[u8IerChn].u8DrvDire)
                {
                    if (stStepPara[u8IerChn].u8StepDrvCnt >= 7)
                    {
                        stStepPara[u8IerChn].u8StepDrvCnt = 0;
                    }
                    else
                    {
                        if (stStepPara[u8IerChn].u8StepDrvCnt < 0xff)
                        {
                            stStepPara[u8IerChn].u8StepDrvCnt++;
                        }
                    }
                }
                else
                {
                    if (0 == stStepPara[u8IerChn].u8StepDrvCnt)
                    {
                        stStepPara[u8IerChn].u8StepDrvCnt = 7;
                    }
                    else
                    {
                        if (stStepPara[u8IerChn].u8StepDrvCnt > 0)
                        {
                            stStepPara[u8IerChn].u8StepDrvCnt--;
                        }
                    }
                }
            }
        }
        else
        {
            //电平维持计时
            if (stStepPara[u8IerChn].u16PaceHoldTim < 0xffff)
            {
                stStepPara[u8IerChn].u16PaceHoldTim++;
            }
        }

        if (0 == stStepInput[u8IerChn].u8DrvDirType)
        {
            stStepOut[u8IerChn].s16PortLev = aStepDrvTab[stStepPara[u8IerChn].u8StepDrvCnt];
        }
        else
        {
            stStepOut[u8IerChn].s16PortLev = aStepDrvRevTab[stStepPara[u8IerChn].u8StepDrvCnt];
        }
    }
    else
    {
        stStepPara[u8IerChn].u8OnceDrvOver = TRUE;

        //上电后当前开度与目标开度首次相等表示复位完成
        if (1 == stStepOut[u8IerChn].u8PowerOnInit)
        {
            stStepOut[u8IerChn].u8RstFinish = TRUE;
        }

        //动作后电平维持时间
        if (stStepPara[u8IerChn].u16PaceHoldTim > U16_STEP_END_TIM)
        {
            stStepOut[u8IerChn].u8ExvBusy = U8_STEP_STA_IDLE;
            stStepOut[u8IerChn].s16PortLev = 0;
        }
        else
        {
            //电平维持计时
            if (stStepPara[u8IerChn].u16PaceHoldTim < 0xffff)
            {
                stStepPara[u8IerChn].u16PaceHoldTim++;
            }
        }
    }
        
    stStepOut[u8IerChn].u16CurPlsOut = stStepPara[u8IerChn].s16CurPls;
}

/******************************************************************************
* Function Name: HalStepInit
* Description: 上电数据初始化
* Output:  void
*******************************************************************************/
void HalStepInit(void)
{
    CommonMemset(&stStepOut, 0x00, sizeof(stStepOut));
    CommonMemset(&stStepPara, 0x00, sizeof(stStepPara));
}

/******************************************************************************
* Function Name: HalStepInput
* Description: 输入更新（或者提供对外改写变量的函数）
* Output:  void
*******************************************************************************/
static void HalStepInput(void)
{
    if (U8_HALMOTOR_CHN0 == u8Chn)
    {
        stStepInput[u8Chn].s16InTargPls = HalStepMotorIn_s16Chn0Pls; 
        stStepInput[u8Chn].u8InDrvSpeedSet = HalStepMotorIn_u8Chn0Spd;
        stStepInput[u8Chn].s16InClosePls = HalStepMotorIn_s16Chn0Closepls;
        stStepInput[u8Chn].u8InStepType = HalStepMotorIn_u8Chn0Type;
        stStepInput[u8Chn].u8DrvDirType = HalStepMotorIn_u8Chn0DrvType;
        stStepInput[u8Chn].s16ResetPls = HalStepMotorIn_s16Chn0RstPls;
    }
    else if (U8_HALMOTOR_CHN1 == u8Chn)
    {
        stStepInput[u8Chn].s16InTargPls = HalStepMotorIn_s16Chn1Pls;
        stStepInput[u8Chn].u8InDrvSpeedSet = HalStepMotorIn_u8Chn1Spd;
        stStepInput[u8Chn].s16InClosePls = HalStepMotorIn_s16Chn1Closepls;
        stStepInput[u8Chn].u8InStepType = HalStepMotorIn_u8Chn1Type; 
        stStepInput[u8Chn].u8DrvDirType = HalStepMotorIn_u8Chn1DrvType;
        stStepInput[u8Chn].s16ResetPls = HalStepMotorIn_s16Chn1RstPls;
    }
    else if (U8_HALMOTOR_CHN2 == u8Chn)
    {
        stStepInput[u8Chn].s16InTargPls = HalStepMotorIn_s16Chn2Pls;
        stStepInput[u8Chn].u8InDrvSpeedSet = HalStepMotorIn_u8Chn2Spd;   
        stStepInput[u8Chn].s16InClosePls = HalStepMotorIn_s16Chn2Closepls;
        stStepInput[u8Chn].u8InStepType = HalStepMotorIn_u8Chn2Type;
        stStepInput[u8Chn].u8DrvDirType = HalStepMotorIn_u8Chn2DrvType;
        stStepInput[u8Chn].s16ResetPls = HalStepMotorIn_s16Chn2RstPls;
    }
    else {}
}
